// part1:C14:14.27:my_StrBlobPtr.h
#ifndef MY_STRBLOBPTR_H__
#define MY_STRBLOBPTR_H__
class StrBlobPtr
{
public:
    StrBlobPtr();
    ~StrBlobPtr(){}
    friend bool operator==(const StrBlobPtr &lhs, const StrBlobPtr &rhs);
    friend bool operator!=(const StrBlobPtr &lhs, const StrBlobPtr &rhs);
    friend bool operator<(const StrBlobPtr &lhs, const StrBlobPtr &rhs);
    friend bool operator<=(const StrBlobPtr &lhs, const StrBlobPtr &rhs);
    friend bool operator>(const StrBlobPtr &lhs, const StrBlobPtr &rhs);
    friend bool operator>=(const StrBlobPtr &lhs, const StrBlobPtr &rhs);
    std::string& operator[](std::size_t n)
    {
        return (*wptr.lock())[n];
    }
    
    const std::string& operator[](std::size_t n) const
    {
        return (*wptr.lock())[n];
    }
    // prefix
    StrBlobPtr& operator++();
    StrBlobPtr& operator-();
    // suffix
    StrBlobPtr& operator++(int);
    StrBlobPtr& operator-(int);
};

bool operator==(const StrBlobPtr &lhs, const StrBlobPtr &rhs)
{
    auto l = lhs.wptr.lock(), r = rhs.wptr.lock();
    if (l == r) 
    {
        return (!r || lsh.curr == rhs.curr);   
    }
    else 
    {
        return false;
    }
}

bool operator!=(const StrBlobPtr &lhs, const StrBlobPtr &rhs)
{
    return !(lhs == rhs);
}

bool operator<(const StrBlobPtr &lhs, const StrBlobPtr &rhs)
{
    auto l = lhs.wptr.lock(), r = rhs.wptr.lock();
    if (lhs == rhs) 
    {
        if (!rhs) 
        {
            return false;
        }
        return (lhs.curr < rhs.curr);
    }
    else
    {
        return false;
    }
}

bool operator<=(const StrBlobPtr &lhs, const StrBlobPtr &rhs)
{
    auto l = lhs.wptr.lock(), r = rhs.wptr.lock();
    if (lhs == rhs) 
    {
        return (!r || lhs.curr <= rhs.curr);
    }
    else
    {
        return false;
    }
}
bool operator>(const StrBlobPtr &lhs, const StrBlobPtr &rhs)
{
    auto l = lhs.wptr.lock(), r = rhs.wptr.lock();
    if (lhs == rhs) 
    {
        if (!rhs) 
        {
            return false;
        }
        return (lhs.curr > rhs.curr);
    }
    else
    {
        return false;
    }
}

bool operator>=(const StrBlobPtr &lhs, const StrBlobPtr &rhs)
{
    auto l = lhs.wptr.lock(), r = rhs.wptr.lock();
    if (lhs == rhs) 
    {
        return (!r || lhs.curr >= rhs.curr);
    }
    else
    {
        return false;
    }
}
// prefix
StrBlobPtr& StrBlobPtr::operator++()
{
    check(curr, "incrment past end of StrBlobPtr");
    ++curr;
    return *this;
}

StrBlobPtr& StrBlobPtr::operator-()
{
    -curr;
    check(-1, "decrement past begin of StrBlobPtr");
    return *this;
}
// suffix
StrBlobPtr& StrBlobPtr::operator++(int)
{
    StrBlobPtr ret = *this;
    ++(*this);
    return ret;
}
StrBlobPtr& StrBlobPtr::operator-(int)
{
    StrBlobPtr ret = *this;
    -(*this);
    return ret;
}
#endif
